package alarm;

import java.util.Arrays;
import java.util.List;

import org.snmp4j.PDU;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.TimeTicks;
import org.snmp4j.smi.VariableBinding;

import features.SNMPClient;
import features.SNMPException;
import features.SNMPSession;
import features.SNMPValue;

public class Event {
	private static final String EVENT_INDEX = 	".1.3.6.1.2.1.16.9.1.1.1";
	private static final String DESCRIPTION = 	".1.3.6.1.2.1.16.9.1.1.2";
	private static final String TYPE = 			".1.3.6.1.2.1.16.9.1.1.3";
	private static final String COMMUNITY = 	".1.3.6.1.2.1.16.9.1.1.4";
//	private static final String LAST_TIME_SENT =".1.3.6.1.2.1.16.9.1.1.5";
	private static final String OWNER = 		".1.3.6.1.2.1.16.9.1.1.6";
	public static final String STATUS = 		".1.3.6.1.2.1.16.9.1.1.7";
	
	private Integer32 eventIndex; //variableIndex > 1
	private OctetString description = new OctetString("");
	private EventType eventType = EventType.logAndTrap; 	
	private OctetString community; //read-only
	private TimeTicks lastTimeSent; 	// risingAlarm(1), fallingAlarm(2), risingOrFallingAlarm(3)
	private OctetString owner; //optional
	private AlarmStatus status = AlarmStatus.createRequest; 		//valid(1), createRequest(2), underCreation(3), invalid(4)
//	private String targetIp; //solo per indetificare il msg nel sistema
	private SNMPSession session;

	public Event() {}
	
	private int getFreeIndex(SNMPSession session) throws SNMPException {
		int freeIndex = 1;
		List<SNMPValue> indexes = session.getColumn(EVENT_INDEX);
		int[] indexesInt = new int[indexes.size()];
		
		for (int i = 0; i < indexes.size(); i++) {
			indexesInt[i] = indexes.get(i).toInt();
		}
		Arrays.sort(indexesInt);
		
		for (int i = 0; i < indexesInt.length; i++) {
			if(freeIndex != indexesInt[i])
				return freeIndex;
			else
				freeIndex++;
		}
		
		return freeIndex;
	}
	
	public void register(SNMPSession session) throws SNMPException {
		this.session = session;
		PDU pdu = null;
		int index = getFreeIndex(session);
		
		this.eventIndex = new Integer32(index);
		
		pdu = new PDU();
		pdu.add(new VariableBinding(new OID(STATUS + "." + index), AlarmStatus.createRequest.toVariable()));
		session.set(pdu);
		
		pdu = new PDU();
		pdu.add(new VariableBinding(new OID(DESCRIPTION + "." + index), description));
		session.set(pdu);
		
		pdu = new PDU();
		pdu.add(new VariableBinding(new OID(TYPE + "." + index), eventType.toVariable()));
		session.set(pdu);
		
		pdu = new PDU();
		pdu.add(new VariableBinding(new OID(COMMUNITY + "." + index), community));
		session.set(pdu);
		
		if(owner != null) {
			pdu = new PDU();
			pdu.add(new VariableBinding(new OID(OWNER + "." + index), owner));
			session.set(pdu);
		}
		
		pdu = new PDU();
		pdu.add(new VariableBinding(new OID(STATUS + "." + index), AlarmStatus.valid.toVariable()));
		session.set(pdu);
		
	}
	
	public void unregister() {
		PDU pdu = new PDU();
		pdu.add(new VariableBinding(new OID(STATUS + "." + eventIndex.toInt()), AlarmStatus.invalid.toVariable()));
		
		session.set(pdu);
	}

	public Integer32 getEventIndex() {
		return eventIndex;
	}

	public void setEventIndex(Integer32 eventIndex) {
		this.eventIndex = eventIndex;
	}

	public OctetString getDescription() {
		return description;
	}

	public void setDescription(OctetString description) {
		this.description = description;
	}

	public EventType getEventType() {
		return eventType;
	}

	public void setEventType(EventType eventType) {
		this.eventType = eventType;
	}

	public OctetString getCommunity() {
		return community;
	}

	public void setCommunity(OctetString community) {
		this.community = community;
	}

	public TimeTicks getLastTimeSent() {
		return lastTimeSent;
	}

	public void setLastTimeSent(TimeTicks lastTimeSent) {
		this.lastTimeSent = lastTimeSent;
	}

	public OctetString getOwner() {
		return owner;
	}

	public void setOwner(OctetString owner) {
		this.owner = owner;
	}

	public AlarmStatus getStatus() {
		return status;
	}

	public void setStatus(AlarmStatus status) {
		this.status = status;
	}

	public SNMPSession getSession() {
		return session;
	}

	public void setSession(SNMPSession session) {
		this.session = session;
	}
	
	public static void unregisterAllEvent(SNMPSession session) throws SNMPException {
		PDU pdu = null;
		List<SNMPValue> indexes = session.getColumn(EVENT_INDEX);
		for (SNMPValue value : indexes) {
			pdu = new PDU();
			pdu.add(new VariableBinding(new OID(STATUS + "." + value.toInt()), AlarmStatus.invalid.toVariable()));
			
			session.set(pdu);
		}
	}
	
	public static void main(String[] args) throws SNMPException {
		SNMPSession session = SNMPClient.startSession(SNMPClient.VERSION_2C);
		session.init("192.2.1.1", SNMPClient.DEFAULT_PORT_STRING, SNMPClient.DEFAULT_COMMUNITY);
		
		unregisterAllEvent(session);
	}
}
